package com.caiyouxi.pay.service;

import com.caiyouxi.common.Constant;
import com.caiyouxi.common.bean.ResData;
import com.caiyouxi.common.exception.ErrorCode;
import com.caiyouxi.common.service.BaseService;
import com.caiyouxi.common.util.Log;
import com.caiyouxi.finance.model.*;
import com.caiyouxi.finance.service.*;
import com.caiyouxi.goods.model.GoodsCategory;
import com.caiyouxi.goods.model.GoodsInfo;
import com.caiyouxi.goods.service.GoodsCategoryService;
import com.caiyouxi.goods.service.GoodsDeliverServiceService;
import com.caiyouxi.goods.service.GoodsInfoService;
import com.caiyouxi.order.model.OrderBean;
import com.caiyouxi.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

@Service
public class AccountPayService extends BaseService{

    @Autowired
    private FinanceTradeReceivedService financeTradeReceivedService;
    @Autowired
    private FinancePaymentDetailService financePaymentDetailService;
    @Autowired
    private GoodsDeliverServiceService goodsDeliverServiceService;
    @Autowired
    private FinanceTradeDetailService financeTradeDetailService;
    @Autowired
    private GoodsInfoService goodsInfoService;
    @Autowired
    private GoodsCategoryService goodsCategoryService;
    @Autowired
    private FinanceTradeReceivableService financeTradeReceivableService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private FinanceAccountService financeAccountService;
    @Autowired
    private FinanceCurrencyService financeCurrencyService;


    /**
     * 非第三方支付
     */
    @Transactional
    public ResData account_pay(OrderBean bean) throws Exception{
        //创建加款的交易明细记录    付款人为用户
        HashMap<String,Object> map = new HashMap();
        map.put("target_id",bean.getId());
        map.put("target_type","ORDER");
        FinanceTradeDetail ftd = financeTradeDetailService.select_finance_trade_details_by_map(map);
        ftd.setFinished_amount(bean.getTotal_amount());
        ftd.setStatus(Constant.FINANCE_STATUS_FINISHED);
        //获取商品的创建订单后的有效时间
        Calendar c = Calendar.getInstance();
        c.setTime(ftd.getCreate_time());
        GoodsInfo gInfo = goodsInfoService.select_goods_info_on_usefull(bean.getGoods_id());
        if(gInfo == null){
            Log.e("商品无效");
            return failed(ErrorCode.SYS_FAIL);
        }
        GoodsCategory goodsCategory = goodsCategoryService.select_goods_category(gInfo.getCategory_id());
        c.add(Calendar.MINUTE,goodsCategory.getOrder_pay_expire_interval());
        ftd.setPay_expire_time(c.getTime());
        
        //创建应收应付流水//创建应收应付记录    key对应款项    jsons.getInteger(key)对应金额
        List<FinanceTradeReceivable> ftrs = financeTradeReceivableService.select_finance_trade_receivable_by_finance_trade_details_id(ftd.getId());
        for(FinanceTradeReceivable ftr : ftrs){
            //先是将用户的对应的支付余额减，加至对应的我方货币类型的内置余额账户
            HashMap<String,Object> m = update_check_finance_account(bean,ftr);
            if(!"SUCCESS".equals(m.get("code"))){
                //说明没处理成功
                Log.e("处理异常" + m.get("msg"));
//                throw new Exception("处理异常" + m.get("msg"));//避免事务提交
                if("PAY_ERROR_BALLANCE_LOW".equals(m.get("code"))){
                    return failed(ErrorCode.PAY_ERROR_BALLANCE_LOW);
                }
                return failed(m.get("code").toString(),m.get("msg").toString(),null);
            }

            //用户信息正常后处理更新
            ftr.setStatus(Constant.FINANCE_STATUS_RECEIVABLE);
            financeTradeReceivableService.update_finance_trade_receivable(ftr);
            //已收已付
            //创建已收已付记录
//            HashMap<String, Object> map1 = new HashMap();
//            map1.put("finance_trade_details_id",ftd.getId());
//            map1.put("finance_trade_receivable_id",ftr.getId());
//            FinanceTradeReceived ftrd = financeTradeReceivedService.select_finance_trade_received_by_receivable_id_and_details_id(map1);
//            if(ftrd != null){
//                ftrd.setStatus(Constant.FINANCE_STATUS_FINISHED);
//                ftrd.setUpdate_time(new Date());
//                financeTradeReceivedService.update_finance_trade_received(ftrd);
//
//                //创建已收已付款项的支付信息
//                financePaymentDetailService.add_finance_payment_detail(bean.getTotal_amount(),ftrd.getId(),bean.getBuyer_user_id(),"RECHARGE","RECHARGE");
//            }

            FinanceTradeReceived ftrd = financeTradeReceivedService.add_finance_trade_received(bean.getTotal_amount(),ftd.getId(),ftr.getId(),Constant.FINANCE_STATUS_FINISHED);
            //创建已收已付款项的支付信息
            financePaymentDetailService.add_finance_payment_detail(bean.getTotal_amount(),ftrd.getId(),bean.getBuyer_user_id(),"RECHARGE","RECHARGE");
        }

        financeTradeDetailService.update_finance_trade_details(ftd);

        //更新订单状态
        bean.setStatus(Constant.ORDER_STATUS_PAIED);//已经确认支付的
        bean.setFinished_amount(bean.getTotal_amount());
        orderService.update_order(bean);

        //更新相关流水记录信息状态
        String status = Constant.FINANCE_STATUS_RECEIVED;//已收/已交账的（待结算的）
        //更新交易流水记录信息状态
        financeTradeDetailService.updateFinanceTradeDetail(bean,status,"ORDER");
        
        //调发货
        Log.d("发货开始------");
        //查询对应商品品类的发货时间
        boolean flag = true;//APP_RECHARGE
        if(bean.getUp_curreny_code() != null && !"".equals(bean.getUp_curreny_code())){
            flag = false;//充值RECHARGE
            goodsDeliverServiceService.push_goods_recharge(bean,flag);
        }
        
        Log.d("发货结束------");

        //更新订单状态
        bean.setStatus(Constant.ORDER_STATUS_FINISHED);//已经确认支付的
        bean.setFinished_amount(bean.getTotal_amount());
        orderService.update_order(bean);

        //更新缓存
        redisService.set("order" + bean.getId(), bean);
        return success(bean);
    }

    /**
     * 账户余额变更(归集至中间账户)
     * @param order
     * 买家余额减，对应的内置账户余额加
     */
    public HashMap<String,Object> update_check_finance_account(OrderBean order,FinanceTradeReceivable ftr) throws Exception{
        String currency_code = order.getCurrency_code();
        if(order.getUp_curreny_code() != null && !"".equals(order.getUp_curreny_code())){
            currency_code = order.getUp_curreny_code();
        }
        HashMap<String,Object> map = new HashMap();
        //买家
        FinanceAccount fa_buy = financeAccountService.select_finance_account_by_uiaccaac(currency_code,order.getAccount_code(),order.getBuyer_user_id());
        //卖家——内置账户 ——gInfo.getSeller_user_id()
        FinanceCurrency financeCurrency = financeCurrencyService.get_finance_currency_by_code(order.getCurrency_code());
        if(null == financeCurrency){
            //货币类型不存在
            Log.e("货币类型不存在");
            map.put("code","FAILD");
            map.put("msg","账户状态异常!");
            return map;
        }
        GoodsInfo gInfo = goodsInfoService.select_goodsInfo_by_id(Long.valueOf(financeCurrency.getRecharge_goods_id()));
        if(null == gInfo){
            //内置货币商品不存在
            Log.e("内置货币商品不存在");
            map.put("code","FAILD");
            map.put("msg","账户状态异常!");
            return map;
        }
        FinanceAccount fa_sell = financeAccountService.select_finance_account_by_uiaccaac(currency_code,order.getAccount_code(),gInfo.getSeller_user_id());
        //买家出款   扣款order.getTotal_amount()/financeCurrency.getRate()
        Log.d("买家出款开始");
        HashMap<String,Object> map1 = financeAccountService.update_finance_account(fa_buy,order.getBuyer_user_id(),- order.getTotal_amount(),Constant.USER_STATUS_CONFIRMED,order.getAccount_code(),ftr.getId(),ftr.getFinance_trade_details_id());
        Log.e("买家出款结束" + order.getBuyer_user_id() + "减款" + order.getTotal_amount());
        if(!"SUCCESS".equals(map1.get("code"))){
            return map1;
        }
        Log.d("卖家入款开始");
        //卖家（内置商品账户）入款
        HashMap<String,Object> map2 = financeAccountService.update_finance_account(fa_sell,gInfo.getSeller_user_id(),order.getTotal_amount(),Constant.USER_STATUS_CONFIRMED,order.getAccount_code(),ftr.getId(),ftr.getFinance_trade_details_id());
        Log.e("卖家入款结束" + gInfo.getSeller_user_id() + "加款" + order.getTotal_amount());
        if(!"SUCCESS".equals(map2.get("code"))){
            return map2;
        }
        map.put("code","SUCCESS");
        map.put("msg","成功!");
        return map;
    }
}
